#!/usr/bin/env python3
import json
import logging.config
import os
import re
import stat
import sys
import tempfile
import threading
import traceback
from distutils.spawn import find_executable
from pathlib import Path
from pipes import quote

from pyaxmlparser import APK
from apkleaks.colors import color as col
from apkleaks.utils import find_format, util


class APKLeaks:
	def __init__(self, args):
		self.apk = None
		# self.file = os.path.realpath(args.file)
		self.json = "--json"
		# self.json = args.json
		# self.disarg = args.args
		self.prefix = "apkleaks-"
		# self.tempdir = tempfile.mkdtemp(prefix=self.prefix)
		# os.makedirs("C:\\Users\\etacao\python\\apkleaks\\decompile\\b")
		# os.chmod("C:\\Users\\etacao\python\\apkleaks\\decompile\\b", stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
		self.tempdir = os.path.abspath("C:\\Users\\etacao\python\\apkleaks\\decompile\\a")
		self.main_dir = os.path.dirname(os.path.realpath(__file__))
		# self.output = tempfile.mkstemp(suffix=".%s" % ("json" if self.json else "txt"), prefix=self.prefix)[1] if args.output is None else args.output
		# self.fileout = open(self.output, "%s" % ("w" if self.json else "a"))
		# self.pattern = os.path.join(str(Path(self.main_dir).parent), "config", "regexes.json") if args.pattern is None else args.pattern
		self.pattern = "C:\\Users\\etacao\\python\\apkleaks\\apkleaks\\pattern.json"
		# self.jadx = find_executable("jadx") if find_executable("jadx") is not None else os.path.join(str(Path(self.main_dir).parent), "jadx", "bin", "jadx%s" % (".bat" if os.name == "nt" else "")).replace("\\","/")
		# self.output = open("C:\\Users\\etacao\\python\\apkleaks\\result.json")
		self.fileout = open("C:\\Users\\etacao\\python\\apkleaks\\result.json", "w")
		self.out_json = {}
		self.scanned = False
		logging.config.dictConfig({"version": 1, "disable_existing_loggers": True})

	def apk_info(self):
		return APK(self.file)

	def integrity(self):
		if os.path.isfile(self.file):
			try:
				self.apk = self.apk_info()
			except Exception as error:
				util.writeln(str(error), col.WARNING)
				sys.exit()
			else:
				return self.apk
		else:
			sys.exit(util.writeln("It's not a valid file!", col.WARNING))

	def decompile(self):
		util.writeln("** Decompiling APK...", col.OKBLUE)
		# 跳过资源文件
		args = [self.jadx, self.file, "-d", self.tempdir, "-r"]
		try:
			args.extend(re.split(r"\s|=", self.disarg))
		except Exception:
			traceback.print_exc()
		comm = "%s" % (" ".join(quote(arg) for arg in args))
		comm = comm.replace("\'","\"")
		os.system(comm)

	def extract(self, name, result):
		self.out_json = result
		# self.fileout.write("%s" % ("\n" if self.json is False else ""))
		#
		# if len(result):
		# 	stdout = ("[%s]" % (name))
		# 	util.writeln("\n" + stdout, col.OKGREEN)
		# 	self.fileout.write("%s" % (stdout + "\n" if self.json is False else ""))
		# 	for secret in matches:
		# 		if name == "LinkFinder":
		# 			if re.match(r"^.(L[a-z]|application|audio|fonts|image|kotlin|layout|multipart|plain|text|video).*\/.+", secret) is not None:
		# 				continue
		# 			secret = secret[len("'"):-len("'")]
		# 		stdout = ("- %s" % (secret))
		# 		print(stdout)
		# 		#修改为我们自己的输出格式json/csv
		# 		self.fileout.write("%s" % (stdout + "\n" if self.json is False else ""))
		# 	self.fileout.write("%s" % ("\n" if self.json is False else ""))
		# 	self.out_json["results"].append({"name": name, "url": matches})
		self.scanned = True
	def scanning(self):
		# if self.apk is None:
		# 	sys.exit(util.writeln("** Undefined package. Exit!", col.FAIL))
		# util.writeln("\n** Scanning against '%s'" % (self.apk.package), col.OKBLUE)
		# self.out_json["package"] = self.apk.package
		# self.out_json["results"] = []
		find = find_format()
		with open(self.pattern) as regexes:
			regex = json.load(regexes)
			#可以指定解析路径为我们需要的解析路径
			scan_path_widget = self.tempdir + "\\sources\\com\\vesync\\"
			print("AA:::" +  scan_path_widget + "\n")
			scan_path_main = self.tempdir + "\\sources\\com\\etekcity\\"
			print("BB:::" + scan_path_main + "\n")
			for name, pattern in regex.items():
				try:
					# thread = threading.Thread(target = self.extract, args = (name, find.finder(pattern, [scan_path_widget, scan_path_main], name)))
					thread = threading.Thread(target = self.extract, args = (name, find.finder(pattern, ["\\sources"], name)))

					thread.start()
				except KeyboardInterrupt:
					sys.exit(util.writeln("\n** Interrupted. Aborting...", col.FAIL))

	def format_result(self, result):
		for key, url_obj in result.items():
			if key == "others":
				result[key] = sorted(list(set(url_obj)))
			else:
				for key_, url_list in url_obj.items():
					url_obj[key_] = sorted(list(set(url_list)))
	def cleanup(self):
		self.format_result(self.out_json)
		#在清除我们反编译目录前添加我们自己的，特殊路劲解析逻辑
		# shutil.rmtree(self.tempdir)
		if self.scanned:
			self.fileout.write("%s" % (json.dumps(self.out_json, indent=4) if self.json else ""))
			# self.fileout.close()
			# print("%s\n** Results saved into '%s%s%s%s'%s." % (col.HEADER, col.ENDC, col.OKGREEN, self.output, col.HEADER, col.ENDC))
		else:
			self.fileout.close()
			# os.remove(self.output)
			util.writeln("\n** Done with nothing. ¯\\_(ツ)_/¯", col.WARNING)


# "options": "@OPTIONS\\(\"(.*?)\"\\)",
# "trace": "@TRACE\\(\"(.*?)\"\\)",
# "connect": "@CONNECT\\(\"(.*?)\"\\)",
# "head": "@HEAD\\(\"(.*?)\"\\)"